package singleton;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @author liouwb
 * 单例模式
 * 懒汉式
 */
public class SingletonLazyTest {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        // 懒汉式
        SingletonLazy lazy = SingletonLazy.getInstance();
        SingletonLazy lazy1 = SingletonLazy.getInstance();

        // 通过反射实例
        Class<SingletonLazy> lazyClass = SingletonLazy.class;
        Constructor<SingletonLazy> constructor = lazyClass.getDeclaredConstructor();

        constructor.setAccessible(true);
        SingletonLazy lazy2 = constructor.newInstance();

        // 验证单例是否全局只有一个实例
        System.out.println("正常获取的实例比较：" + (lazy == lazy1));
        System.out.println("正常获取实例与反射获取比较：" + (lazy == lazy2));

        // 输出对象信息
        System.out.println("lazy ：" + lazy);
        System.out.println("lazy1：" + lazy1);
        System.out.println("lazy2：" + lazy2);

    }

    /**
     * 懒汉式
     */
    static class SingletonLazy {
        //
        public static SingletonLazy instance;

        private static boolean flag = false;

        // 私有构造函数
        private SingletonLazy() {
            synchronized (SingletonLazy.class) {
                if (!flag) {
                    flag = true;
                } else {
                    throw new RuntimeException("不要用反射破坏单例");
                }
            }
        }

        public static SingletonLazy getInstance() {
            if (instance == null) {
                instance = new SingletonLazy();
            }

            return instance;
        }
    }
}
